import { defineStore } from "pinia";
import { getToken, removeToken, setToken } from "../utils/token-utils";
import type { UserInfoState } from "./interface";
import { staticRoutes, allAsyncRoutes, anyRoute } from "@/router/routes";
import { loginApi, logoutApi, getUserInfoApi } from "@/api/acl/login";
import type { RouteRecordRaw } from "vue-router";
import router from "../router";
/**
 * 过滤得到用户拥有访问权限的路由表
 * @param allAsyncRoutes 所有异步路由菜单
 * @param routes 用户路由权限值
 */
const getPermissionRoutes = (
  allAsyncRoutes: RouteRecordRaw[],
  routes: string[]
) => {
  return allAsyncRoutes.filter((route) => {
    // 判断父级菜单是否包含权限值
    if (routes.includes(route.name as string)) {
      // 如果有子菜单，子菜单也要进行过滤
      if (route.children && route.children.length > 0) {
        route.children = getPermissionRoutes(route.children, routes);
      }
      return true;
    }
    return false;
  });
};

/**
 * 动态添加路由表
 * @param hasPermissionRoutes 用户拥有访问权限的路由表
 */
const addRoutes = (hasPermissionRoutes: RouteRecordRaw[]) => {
  hasPermissionRoutes.forEach((route) => {
    // 动态添加路由
    router.addRoute(route);
  });
};

export const useUserInfoStore = defineStore("userInfo", {
  state: (): UserInfoState => ({
    token: getToken() as string,
    name: "", // 用户名
    avatar: "", // 用户头像
    routes: [], // 路由权限列表：决定哪些路由组件可以访问
    buttons: [], // 按钮权限列表：决定哪些按钮可以访问
    menuRoutes: [], // 菜单权限列表
  }),

  actions: {
    async login(username: string, password: string) {
      // 发送请求登录
      const { token } = await loginApi(username, password);
      // 登录成功将token存储起来
      this.token = token; // 存在pinia中
      setToken(token);
    },

    // 登出
    async reset() {
      // 删除服务器的token
      await logoutApi();
      // 删除local中保存的token
      removeToken();
      // 删除pinia中的数据
      this.token = "";
      this.name = "";
      this.avatar = "";
    },
    // 获取用户信息
    async getInfo() {
      const { name, avatar, routes, buttons } = await getUserInfoApi();
      // 用户名和头像在头部展示
      this.name = name;
      this.avatar = avatar;
      // 用来管理权限
      this.routes = routes;
      this.buttons = buttons;

      // 1. 根据用户路由权限值和所有异步路由表进行过滤，得到用户拥有访问权限的路由表hasPermissionRoutes
      // 根据用户的路由权限，来动态加载异步路由表
      const hasPermissionRoutes = getPermissionRoutes(allAsyncRoutes, routes);

      // 2. 将用户拥有访问权限的路由表追加到路由配置中才能访问
      // 将异步路由表添加到路由配置项中才能访问
      addRoutes(hasPermissionRoutes);

      // 3. 将路由表更新到menuRoutes，将来左侧菜单就会根据menuRoutes的值来遍历生成左侧菜单
      // 左侧菜单要渲染的路由表
      this.menuRoutes = staticRoutes;
      // 只是渲染左侧菜单
      this.menuRoutes = [...staticRoutes, ...hasPermissionRoutes, anyRoute];
    },
  },
});
